package filter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.BaseBean;
import model.DefaultParams;
import model.XMLBean;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import action.ActionManager;

import common.StrutsStaticParams;

import parser.DefaultValue;
import parser.XMLParser;
import utils.BeanUtils;

public class StrutsFilter implements Filter 
{
	private Map<String, String> defaultParams = null;
	private Map<String, BaseBean> baseBean = null;
	
	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException 
	{
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		if(this.defaultParams == null)
			this.defaultParams = (Map<String, String>) request.getSession().getServletContext().getAttribute(StrutsStaticParams.DEFAULT_PARAMS_MAP);
		if(this.baseBean == null)
			this.baseBean = (Map<String, BaseBean>) request.getSession().getServletContext().getAttribute(StrutsStaticParams.BASEBEAN);
		
		String servletPath = request.getServletPath();
		int actionNamePoint = servletPath.lastIndexOf(".");
		if(servletPath.substring(actionNamePoint + 1).equals(this.defaultParams.get("AccessMethod")))
		{		
			BaseBean bean = baseBean.get(servletPath.substring(1, actionNamePoint));
			if(bean == null)
				response.getWriter().write("<h1>404 not found</h1>");
			else
			{
				XMLBean xmlBean = (XMLBean) bean;
				String actionClassPath = xmlBean.getClassPath();
				ActionManager manager = new ActionManager();
				String result = manager.ManagerDriven(actionClassPath, request);
				request.getRequestDispatcher(result).forward(request, response);
			}
		}
		else
			response.getWriter().write("<h1>404 not found</h1>");
	}

	public void init(FilterConfig config) throws ServletException {
		String filePath = config.getInitParameter(StrutsStaticParams.STRUTS_CONFIG_NAME).replace("/", "\\");
		String realFilePath = "";
		if(filePath.indexOf('\\') == 0)
			realFilePath = config.getServletContext().getRealPath("/") + filePath.substring(1);
		else
			realFilePath = this.getClass().getResource("/").getPath().substring(1) + filePath;
		
		File file = new File(realFilePath);
		if(!file.isFile())
			throw new ServletException();
		else
		{
			try 
			{
				Map<String, BaseBean> baseBean = XMLParser.parserXML(file);
				
				DefaultValue defaultValue = new DefaultValue();
				Map<String, String> params = defaultValue.getParams();
				
				DefaultParams dp = (DefaultParams) baseBean.get(StrutsStaticParams.DEFAULTPARAMS);
				
				if(dp != null)
					BeanUtils.strutsDefaultParamsTransform(dp, params);
				
				config.getServletContext().setAttribute(StrutsStaticParams.BASEBEAN, baseBean);
				config.getServletContext().setAttribute(StrutsStaticParams.DEFAULT_PARAMS_MAP, params);
			} catch (DocumentException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
	}
}
